﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.Xml;
using System.Data;
using SMSPanasonic.Business;

namespace SMSPanasonic
{
    class SMSGetMTReport
    {
        private EventLog _serviceEventLog;
        private bool _thread_working_flag = false;
        private int _thread_id;
        private bool _serviceStarted;
        private int _interval = Properties.Settings.Default.IntevalDefaultGetReport;
        private SmsRouter _sms_router;
        private static int usingResource = 0;
        private static Dictionary<int, DateTime> smsRouterWarningTime = new Dictionary<int, DateTime>();

        public SMSGetMTReport(int thread_id, SmsRouter sms_router, EventLog serviceEventLog)
        {
            this._sms_router = sms_router;
            this._thread_id = thread_id;
            this._serviceEventLog = serviceEventLog;
        }
        public bool ServiceStarted
        {
            get
            {
                return _serviceStarted;
            }
            set
            {
                _serviceStarted = value;
            }
        }
        public int Interval
        {
            get
            {
                return _interval;
            }
        }

        public void ExecuteTask()
        {
            DateTime lastRunTime = DateTime.Now;

            // TODO: Add code here to start your service.
            //_serviceEventLog.WriteEntry("SMSPanasonicGetMTReport service started=>Thread: " + this._thread_id.ToString() + "; RouterID: " + (this._sms_router.RouterID.IsNull ? "" : this._sms_router.RouterID.Value.ToString()) + "; RouterName: " + (this._sms_router.RouterName.IsNull ? "" : this._sms_router.RouterName.Value), EventLogEntryType.Information);
            while (_serviceStarted)
            {
                // check the current time against the last run plus interval
                if (((TimeSpan)(DateTime.Now.Subtract(lastRunTime))).TotalMilliseconds >= _interval && !_thread_working_flag)
                {
                    _thread_working_flag = true;
                    try
                    {
                        if (Common.isDatabaseAlive(Properties.Settings.Default.ConnectionString) == ConnectionState.Open)
                        {
                            int iCountReport = 0;
                            //Kiem tra neu co MT Pending moi goi (trang thai la SENT-SAMI)
                            while (0 != Interlocked.Exchange(ref usingResource, 1))
                            {
                                Thread.Sleep(50);
                            }

                            iCountReport = SmsMtReport.GetCount(" Status = 'SENT-SAMI' ");
                            //Release the lock
                            Interlocked.Exchange(ref usingResource, 0);


                            string url_alive = "";
                            if (iCountReport > 0)
                            {
                                //Kiem tra router con song khong truoc khi goi
                                if (Common.WebSerivceIsAvailable(this._sms_router, ref url_alive))
                                {
                                    //Lay report

                                    SAMI_SMSService.SMSWebService service = new SMSPanasonic.SAMI_SMSService.SMSWebService();
                                    service.Url = url_alive;

                                    string return_message = "";
                                    int CooperateID = Properties.Settings.Default.CooperateID; // 9; //Mã đang cấp cho HSG là 9
                                    string inputString = DateTime.Now.ToLongTimeString(); //Lấy thời gian hiện tại để mã hóa

                                    //PublicKey này cấp cho HSG
                                    string strPublicKey = this._sms_router.PublicKey.Value; // "<BitStrength>512</BitStrength><RSAKeyValue><Modulus>wJfwajm09Bny9ruEHW3R8m9tqfy283gLmTnAmhrFH0ajCW7LzUFOIc0LHd2cU3uNxV8LbsEzqlOKrBS9S7cEcw==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

                                    string bitStrengthString = strPublicKey.Substring(0, strPublicKey.IndexOf("</BitStrength>") + 14);
                                    strPublicKey = strPublicKey.Replace(bitStrengthString, "");
                                    int bitStrength = Convert.ToInt32(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));

                                    //Sinh MD5 cho chuỗi xml - Hàm SendEncryptSMSMessage sẽ giải mã chuỗi XML sau đó kiểm tra CheckSum xem nội dung có bị thay đổi không
                                    string checksum = Cryptography.getMd5Hash(inputString);
                                    //Mã hóa XML bằng PublicKey
                                    inputString = Cryptography.EncryptString(inputString, bitStrength, strPublicKey);

                                    try
                                    {
                                        int iResult = service.GetEncryptMTStatusReport(CooperateID, ref inputString, ref checksum, ref return_message);
                                    }
                                    catch (Exception ex)
                                    {
                                        //Thong bao Router da die, khong the ket noi duoc
                                        if (!smsRouterWarningTime.ContainsKey(this._sms_router.RouterID.Value))
                                        {
                                            smsRouterWarningTime.Add(this._sms_router.RouterID.Value, DateTime.Now);
                                            //Dua ra thong bao 10 phut 1 lan
                                            Logs logs = new Logs();
                                            logs.LogSource = System.Data.SqlTypes.SqlString.Null;
                                            logs.LogMessage = "ERROR-SMSPanasonicRouter(" + this._sms_router.RouterName + ") Thread:" + this._thread_id.ToString() + "=> " + ex.Message + (this._sms_router.RouterURL.IsNull ? "" : this._sms_router.RouterURL.Value) + (this._sms_router.RouterURL2.IsNull ? "" : ";" + this._sms_router.RouterURL2.Value);
                                            logs.LogTime = DateTime.Now;
                                            logs.LogTrace = System.Data.SqlTypes.SqlString.Null;
                                            logs.LogType = "MTROUTER";
                                            logs.Status = new System.Data.SqlTypes.SqlBoolean(true);
                                            logs.Save();
                                        }
                                        else
                                        {
                                            if (((TimeSpan)(DateTime.Now.Subtract(smsRouterWarningTime[this._sms_router.RouterID.Value]))).TotalMinutes > Properties.Settings.Default.IntervalSystemAlert)
                                            {
                                                //Dua ra thong bao 10 phut 1 lan
                                                Logs logs = new Logs();
                                                logs.LogSource = System.Data.SqlTypes.SqlString.Null;
                                                logs.LogMessage = "ERROR-SMSPanasonicRouter(" + this._sms_router.RouterName + ") Thread:" + this._thread_id.ToString() + "=> " + ex.Message + (this._sms_router.RouterURL.IsNull ? "" : this._sms_router.RouterURL.Value) + (this._sms_router.RouterURL2.IsNull ? "" : ";" + this._sms_router.RouterURL2.Value);
                                                logs.LogTime = DateTime.Now;
                                                logs.LogTrace = System.Data.SqlTypes.SqlString.Null;
                                                logs.LogType = "MTROUTER";
                                                logs.Status = new System.Data.SqlTypes.SqlBoolean(true);
                                                logs.Save();
                                                smsRouterWarningTime[this._sms_router.RouterID.Value] = DateTime.Now;
                                            }
                                        }
                                    }
                                    finally
                                    {
                                        if (inputString != "" && checksum != "")
                                        {
                                            //Giải mã inputString để lấy Status
                                            //PublicPrivateKey này cấp cho HSG, sử dụng để giải mã Status
                                            string strPublicPrivateKey = this._sms_router.PublicPrivateKey.Value; // "<BitStrength>512</BitStrength><RSAKeyValue><Modulus>9fCs1YZ1+yum6HdCM0XaHnf3bykAWdfhkjh/wzs5ZjyEafUjUdrRFF7zzpZ1x0oo8WGnWNu5s5yBW8zmzUoazw==</Modulus><Exponent>AQAB</Exponent><P>+0r05NMZiWVoASzeYKftXNTWzRRBEQ4EEUqz9OdI7l0=</P><Q>+owM7Ps1mmVlhuum1t5TN8ikIJj5uReM9iFht7FnYxs=</Q><DP>0csgbTF4bmbEz8Zf2Z4Y4pmmwwwXzl8/MhiF6P52utk=</DP><DQ>yGyEYobKaIo4X2fffP84vuUoNlNpYSFvx+0ISHQH6oU=</DQ><InverseQ>fgyDRIv4r2kEJe9lKPbZLGpbURibHEBCj62zP4Cex3M=</InverseQ><D>xhnPzcqZ+/AkaHmvfEdWs1Ykm4hmPPgUPUh/OQ3aZUrjjuCpFxGKSoj1PtlS0OZbcN2XTvS6ISuDU6C+JKJ/OQ==</D></RSAKeyValue>";
                                            bitStrengthString = strPublicPrivateKey.Substring(0, strPublicPrivateKey.IndexOf("</BitStrength>") + 14);
                                            strPublicPrivateKey = strPublicPrivateKey.Replace(bitStrengthString, "");
                                            bitStrength = Convert.ToInt32(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));

                                            //string report = "";
                                            string receivedDecryptMessage = Cryptography.DecryptString(inputString, bitStrength, strPublicPrivateKey);
                                            string receivedMD5CheckSum = Cryptography.getMd5Hash(receivedDecryptMessage);
                                            StringComparer comparer = StringComparer.OrdinalIgnoreCase;
                                            //Kiểm tra nếu đúng check SUM thì cho phép thực hiện
                                            if (0 == comparer.Compare(receivedMD5CheckSum, checksum))
                                            {
                                                //Nạp nội dung giải mã đưa vào trong DataSet.
                                                XmlDocument xDoc = new XmlDocument();
                                                xDoc.LoadXml(receivedDecryptMessage);
                                                DataSet dsContent = (DataSet)Xml.Deserialize(xDoc.DocumentElement, typeof(DataSet));
                                                //Duyệt DataSet
                                                if (dsContent.Tables.Count > 0)
                                                {
                                                    List<string> cooperateGuid = new List<string>();
                                                    for (int i = 0; i < dsContent.Tables[0].Rows.Count; i++)
                                                    {
                                                        SmsMtStatistic smsMtStatistic = new SmsMtStatistic(new Guid(dsContent.Tables[0].Rows[i]["CooperateGUID"].ToString()));
                                                        if (!smsMtStatistic.MtGuid.IsNull)
                                                        {
                                                            smsMtStatistic.Status = dsContent.Tables[0].Rows[i]["Status"].ToString();
                                                            smsMtStatistic.SentTime = ((System.Data.SqlTypes.SqlDateTime)(dsContent.Tables[0].Rows[i]["ReportTime"])).Value;
                                                            smsMtStatistic.Save();
                                                        }

                                                        SmsMtReport.Delete(new Guid(dsContent.Tables[0].Rows[i]["CooperateGUID"].ToString()));
                                                        cooperateGuid.Add(dsContent.Tables[0].Rows[i]["CooperateGUID"].ToString());
                                                    }
                                                    //Xoa Report.
                                                    return_message = "";
                                                    inputString = DateTime.Now.ToLongTimeString(); //Lấy thời gian hiện tại để mã hóa
                                                    //Sinh MD5 cho chuỗi xml
                                                    checksum = Cryptography.getMd5Hash(inputString);
                                                    //Mã hóa XML bằng PublicKey
                                                    inputString = Cryptography.EncryptString(inputString, bitStrength, strPublicKey);
                                                    int iResult = service.DeleteEncryptReport(CooperateID, inputString, checksum, cooperateGuid.ToArray(), ref return_message);
                                                }
                                            }
                                        }

                                    } //end finally

                                }
                                else
                                {
                                    //Thong bao Router da die, khong the ket noi duoc
                                    if (!smsRouterWarningTime.ContainsKey(this._sms_router.RouterID.Value))
                                    {
                                        smsRouterWarningTime.Add(this._sms_router.RouterID.Value, DateTime.Now);
                                        //Dua ra thong bao 10 phut 1 lan
                                        Logs logs = new Logs();
                                        logs.LogSource = System.Data.SqlTypes.SqlString.Null;
                                        logs.LogMessage = "ERROR-SMSPanasonicRouter(" + this._sms_router.RouterName + ") Thread:" + this._thread_id.ToString() + "=> " + "Khong ket noi duoc server:URL:" + (this._sms_router.RouterURL.IsNull ? "" : this._sms_router.RouterURL.Value) + (this._sms_router.RouterURL2.IsNull ? "" : ";" + this._sms_router.RouterURL2.Value);
                                        logs.LogTime = DateTime.Now;
                                        logs.LogTrace = System.Data.SqlTypes.SqlString.Null;
                                        logs.LogType = "MTROUTER";
                                        logs.Status = new System.Data.SqlTypes.SqlBoolean(true);
                                        logs.Save();
                                    }
                                    else
                                    {
                                        if (((TimeSpan)(DateTime.Now.Subtract(smsRouterWarningTime[this._sms_router.RouterID.Value]))).TotalMinutes > Properties.Settings.Default.IntervalSystemAlert)
                                        {
                                            //Dua ra thong bao 10 phut 1 lan
                                            Logs logs = new Logs();
                                            logs.LogSource = System.Data.SqlTypes.SqlString.Null;
                                            logs.LogMessage = "ERROR-SMSPanasonicRouter(" + this._sms_router.RouterName + ") Thread:" + this._thread_id.ToString() + "=> " + "Khong ket noi duoc server:URL:" + (this._sms_router.RouterURL.IsNull ? "" : this._sms_router.RouterURL.Value) + (this._sms_router.RouterURL2.IsNull ? "" : ";" + this._sms_router.RouterURL2.Value);
                                            logs.LogTime = DateTime.Now;
                                            logs.LogTrace = System.Data.SqlTypes.SqlString.Null;
                                            logs.LogType = "MTROUTER";
                                            logs.Status = new System.Data.SqlTypes.SqlBoolean(true);
                                            logs.Save();
                                            smsRouterWarningTime[this._sms_router.RouterID.Value] = DateTime.Now;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ext)
                    {
                        try
                        {
                            Common.WriteLog(ext, "GetMTReport");
                        }
                        catch (Exception extend)
                        {
                            _serviceEventLog.WriteEntry(extend.Message);
                        }
                    }
                    finally
                    {
                        _thread_working_flag = false;
                    }
                }

                // yield
                if (_serviceStarted)
                {
                    Thread.Sleep(new TimeSpan(0, 0, 0, 0, 100));
                }
            }
            _serviceEventLog.WriteEntry("SMSPanasonicGetMTReport service stoped=>Thread: " + this._thread_id.ToString() + "; RouterID: " + (this._sms_router.RouterID.IsNull ? "" : this._sms_router.RouterID.Value.ToString()) + "; RouterName: " + (this._sms_router.RouterName.IsNull ? "" : this._sms_router.RouterName.Value), EventLogEntryType.Information);
            Thread.CurrentThread.Abort();
        }

    }
}